

//% color="#ff9f06" iconWidth=50 iconHeight=40
namespace Sentry3 {
    //% block=" Initialize  Sentry3[SENTRY_INDEX]  port [MODE] addr [ADDR]" blockType="command"
    //% SENTRY_INDEX.shadow="dropdown" SENTRY_INDEX.options="SENTRY_INDEX" SENTRY_INDEX.defl="1"
    //% MODE.shadow="dropdown" MODE.options="MODE"
    //% ADDR.shadow="dropdown" ADDR.options="SENTRY"
    export function Begin(parameter: any) {
        let index = parameter.SENTRY_INDEX.code;
        let mode = parameter.MODE.code;
        let addr = parameter.ADDR.code;

        Generator.addInclude("ArduinoInclude", "#include <Arduino.h>");
        Generator.addInclude("SentryInclude", "#include <Sentry.h>");

        Generator.addObject(`sentry3_${index}.Object`, "Sentry3", `sentry3_${index}(${addr});`);

        if (mode == 'Wire') {
            Generator.addInclude("WireInclude", "#include <Wire.h>");
            Generator.addSetupMainTop("Wire.begin", `Wire.begin();`);
        }

        Generator.addCode(`while (SENTRY_OK != sentry3_${index}.begin(&${mode})) {yield();}`);
    }

    //% block=" Set  Sentry3[SENTRY_INDEX]  light color [DETECTED_COLOR] when targets were detected otherwise [UNDETECTED_COLOR] luma(1-15) [LEVAL] " blockType="command"
    //% SENTRY_INDEX.shadow="dropdown" SENTRY_INDEX.options="SENTRY_INDEX" SENTRY_INDEX.defl="1"
    //% DETECTED_COLOR.shadow="dropdown" DETECTED_COLOR.options="LED_COLOR"
    //% UNDETECTED_COLOR.shadow="dropdown" UNDETECTED_COLOR.options="LED_COLOR"  
    //% LEVAL.shadow="range"  LEVAL.params.min=1   LEVAL.params.max=15   LEVAL.defl=1  
    export function LedSetColor(parameter: any) {
        let index = parameter.SENTRY_INDEX.code;
        let detected_color = parameter.DETECTED_COLOR.code;
        let undetected_color = parameter.UNDETECTED_COLOR.code;
        let leval = parameter.LEVAL.code;
        Generator.addCode(`sentry3_${index}.LedSetColor(${detected_color},${undetected_color},${leval});`);
    }

    //% block=" Set  Sentry3[SENTRY_INDEX]  [VISION_STA]  algo [VISION_TYPE]" blockType="command"
    //% SENTRY_INDEX.shadow="dropdown" SENTRY_INDEX.options="SENTRY_INDEX" SENTRY_INDEX.defl="1"
    //% VISION_TYPE.shadow="dropdown" VISION_TYPE.options="VISION_TYPE_ALL"
    //% VISION_STA.shadow="dropdown" VISION_STA.options="VISION_STA"   
    export function VisionSetStatus(parameter: any) {
        let index = parameter.SENTRY_INDEX.code;
        let vision_type = parameter.VISION_TYPE.code;
        let vision_sta = parameter.VISION_STA.code;
        if (vision_sta == "ON") {
            Generator.addCode(`sentry3_${index}.VisionBegin(${vision_type});`);
        } else {
            Generator.addCode(`sentry3_${index}.VisionEnd(${vision_type});`);
        }

    }

    //% block=" Set  Sentry3[SENTRY_INDEX]  algo[VISION_TYPE]   [NUM] sets of params" blockType="command"
    //% SENTRY_INDEX.shadow="dropdown" SENTRY_INDEX.options="SENTRY_INDEX" SENTRY_INDEX.defl="1"
    //% VISION_TYPE.shadow="dropdown" VISION_TYPE.options="VISION_TYPE_PARMA_NUM" VISION_TYPE.defl="Sentry3::kVisionColor"
    //% NUM.shadow="range"  NUM.params.min=1   NUM.params.max=25   NUM.defl=1
    export function VisionSetParamNum(parameter: any) {
        let index = parameter.SENTRY_INDEX.code;
        let vision_type = parameter.VISION_TYPE.code;
        let num = parameter.NUM.code;
        Generator.addCode(`sentry3_${index}.SetParamNum(${vision_type},(int)${num});`);
    }

    //% block=" Set  Sentry3[SENTRY_INDEX]  algo Color  x-coord[XVALUE] y-coord [YVALUE] width[WIDTH] height[HIGHT] paramset[NUM]"
    //% SENTRY_INDEX.shadow="dropdown" SENTRY_INDEX.options="SENTRY_INDEX" SENTRY_INDEX.defl="1"
    //% NUM.shadow="range"  NUM.params.min=1   NUM.params.max=25   NUM.defl=1
    //% XVALUE.shadow="number"  XVALUE.defl=50
    //% YVALUE.shadow="number"  YVALUE.defl=50
    //% WIDTH.shadow="number"  WIDTH.defl=3
    //% HIGHT.shadow="number"  HIGHT.defl=4
    export function VisionColorSetParam(parameter: any) {
        let index = parameter.SENTRY_INDEX.code;
        let num = parameter.NUM.code;
        let x = parameter.XVALUE.code;
        let y = parameter.YVALUE.code;
        let w = parameter.WIDTH.code;
        let h = parameter.HIGHT.code;

        Generator.addObject("param_obj", "sentry_object_t", `param;`);
        Generator.addCode(`param.x_value = ${x};`);
        Generator.addCode(`param.y_value = ${y};`);
        Generator.addCode(`param.width = ${w};`);
        Generator.addCode(`param.height = ${h};`);
        Generator.addCode(`param.label = 0;`);
        Generator.addCode(`sentry3_${index}.SetParam(Sentry3::kVisionColor,&param,(int)${num});`);
    }
    //% block=" Set  Sentry3[SENTRY_INDEX]  algo Blob  min-width[WIDTH] min-height[HIGHT] color [COLOR_LABLE] paramset[NUM]" blockType="command"
    //% SENTRY_INDEX.shadow="dropdown" SENTRY_INDEX.options="SENTRY_INDEX" SENTRY_INDEX.defl="1"
    //% NUM.shadow="range"  NUM.params.min=1   NUM.params.max=25   NUM.defl=1
    //% WIDTH.shadow="number"  WIDTH.defl=3
    //% HIGHT.shadow="number"  HIGHT.defl=4
    //% COLOR_LABLE.shadow="dropdown" COLOR_LABLE.options="COLOR_LABLE"
    export function VisionBlobSetParam(parameter: any) {
        let index = parameter.SENTRY_INDEX.code;
        let num = parameter.NUM.code;
        let l = parameter.COLOR_LABLE.code;
        let w = parameter.WIDTH.code;
        let h = parameter.HIGHT.code;

        Generator.addObject("param_obj", "sentry_object_t", `param;`);
        Generator.addCode(`param.x_value = 0;`);
        Generator.addCode(`param.y_value = 0;`);
        Generator.addCode(`param.width = ${w};`);
        Generator.addCode(`param.height = ${h};`);
        Generator.addCode(`param.label = ${l};`);
        Generator.addCode(`sentry3_${index}.SetParam(Sentry3::kVisionBlob,&param,(int)${num});`);
    }

    //% block=" Set  Sentry3[SENTRY_INDEX]  algo Blob  max num of blobs for each color(1-5)[MODE]"
    //% SENTRY_INDEX.shadow="dropdown" SENTRY_INDEX.options="SENTRY_INDEX" SENTRY_INDEX.defl="1"
    //% MODE.shadow="range"  MODE.params.min=1   MODE.params.max=5   MODE.defl=1
    export function VisionSetBlobNum(parameter: any) {
        let index = parameter.SENTRY_INDEX.code;
        let mode = parameter.MODE.code;
        Generator.addCode(`sentry3_${index}.VisionSetMode(Sentry3::kVisionBlob,  (int)${mode});`);
    }

    //% block=" Set  Sentry3[SENTRY_INDEX]  algo AprilTag  format[MODE]"
    //% SENTRY_INDEX.shadow="dropdown" SENTRY_INDEX.options="SENTRY_INDEX" SENTRY_INDEX.defl="1"
    //% MODE.shadow="dropdown" MODE.options="APRILTAG_MODE"
    export function VisionSetAprilTagMode(parameter: any) {
        let index = parameter.SENTRY_INDEX.code;
        let mode = parameter.MODE.code;
        Generator.addCode(`sentry3_${index}.VisionSetMode(Sentry3::kVisionAprilTag,  ${mode});`);
    }

    //% block=" Set  Sentry3[SENTRY_INDEX]  algo Line  max num of lines(1-5)[MODE]"
    //% SENTRY_INDEX.shadow="dropdown" SENTRY_INDEX.options="SENTRY_INDEX" SENTRY_INDEX.defl="1"
    //% MODE.shadow="range"  MODE.params.min=1   MODE.params.max=5   MODE.defl=1
    export function VisionSetLineNum(parameter: any) {
        let index = parameter.SENTRY_INDEX.code;
        let mode = parameter.MODE.code;
        Generator.addCode(`sentry3_${index}.VisionSetMode(Sentry3::kVisionLine,  (int)${mode});`);
    }

    //% block=" Set  Sentry3[SENTRY_INDEX]  algo[VISION_TYPE]  [COLOR_LABLE] ID [NUM]"
    //% SENTRY_INDEX.shadow="dropdown" SENTRY_INDEX.options="SENTRY_INDEX" SENTRY_INDEX.defl="1"
    //% VISION_TYPE.shadow="dropdown" VISION_TYPE.options="OPERA_VISION"
    //% NUM.shadow="range"  NUM.params.min=1   NUM.params.max=11   NUM.defl=1
    //% COLOR_LABLE.shadow="dropdown" COLOR_LABLE.options="OPERA_PARAM"
    export function VisionSetParam(parameter: any) {
        let index = parameter.SENTRY_INDEX.code;
        let vision_type = parameter.VISION_TYPE.code;
        let num = parameter.NUM.code;
        let l = parameter.COLOR_LABLE.code;

        Generator.addObject("param_obj", "sentry_object_t", `param;`);
        Generator.addCode(`param.x_value = 0;`);
        Generator.addCode(`param.y_value = 0;`);
        Generator.addCode(`param.width = 0;`);
        Generator.addCode(`param.height = 0;`);
        Generator.addCode(`param.label = ${l};`);
        Generator.addCode(`sentry3_${index}.SetParam(${vision_type},&param,(int)${num});`);
    }

    //% block=" Set  Sentry3[SENTRY_INDEX]  algo BarCode  format[MODE]"
    //% SENTRY_INDEX.shadow="dropdown" SENTRY_INDEX.options="SENTRY_INDEX" SENTRY_INDEX.defl="1"
    //% MODE.shadow="dropdown" MODE.options="BARCODE_MODE"
    export function VisionSetBarCodeMode(parameter: any) {
        let index = parameter.SENTRY_INDEX.code;
        let mode = parameter.MODE.code;
        Generator.addCode(`sentry3_${index}.VisionSetMode(Sentry3::kVisionBarCode,  ${mode});`);
    }
    
    //% block="  Sentry3[SENTRY_INDEX]  algo[VISION_TYPE]  num of results" blockType="reporter"
    //% SENTRY_INDEX.shadow="dropdown" SENTRY_INDEX.options="SENTRY_INDEX" SENTRY_INDEX.defl="1"
    //% VISION_TYPE.shadow="dropdown" VISION_TYPE.options="VISION_TYPE_ALL"   
    export function VisionDetectedCount(parameter: any) {
        let index = parameter.SENTRY_INDEX.code;
        let vision_type = parameter.VISION_TYPE.code;
        Generator.addCode([`sentry3_${index}.GetValue(${vision_type}, kStatus)`, Generator.ORDER_UNARY_POSTFIX]);
    }


    //% block="  Sentry3[SENTRY_INDEX]  algo Color  [OBJ_INFO] of result [NUM]" blockType="reporter"
    //% SENTRY_INDEX.shadow="dropdown" SENTRY_INDEX.options="SENTRY_INDEX" SENTRY_INDEX.defl="1"
    //% NUM.shadow="number" NUM.defl=1
    //% OBJ_INFO.shadow="dropdown" OBJ_INFO.options="OBJ_INFO_COLOR"   
    export function GetVisionObjColorValue(parameter: any) {
        let index = parameter.SENTRY_INDEX.code;
        let num = parameter.NUM.code;
        let obj = parameter.OBJ_INFO.code;
        Generator.addCode([`sentry3_${index}.GetValue(Sentry3::kVisionColor,${obj},(int)${num})`, Generator.ORDER_UNARY_POSTFIX]);
    }

    //% block="  Sentry3[SENTRY_INDEX]  algo[VISION_TYPE]   [OBJ_INFO] of result [NUM]" blockType="reporter"
    //% SENTRY_INDEX.shadow="dropdown" SENTRY_INDEX.options="SENTRY_INDEX" SENTRY_INDEX.defl="1"
    //% VISION_TYPE.shadow="dropdown" VISION_TYPE.options="VISION_TYPE_VALUE"
    //% NUM.shadow="number"  NUM.defl=1
    //% OBJ_INFO.shadow="dropdown" OBJ_INFO.options="OBJ_INFO"   
    export function GetVisionObjValue(parameter: any) {
        let index = parameter.SENTRY_INDEX.code;
        let vision_type = parameter.VISION_TYPE.code;
        let num = parameter.NUM.code;
        let obj = parameter.OBJ_INFO.code;
        Generator.addCode([`sentry3_${index}.GetValue(${vision_type},${obj},(int)${num})`, Generator.ORDER_UNARY_POSTFIX]);
    }

    //% block="  Sentry3[SENTRY_INDEX]  algo Line   [OBJ_INFO] of result [NUM]" blockType="reporter"
    //% SENTRY_INDEX.shadow="dropdown" SENTRY_INDEX.options="SENTRY_INDEX" SENTRY_INDEX.defl="1"
    //% NUM.shadow="number" NUM.defl=1
    //% OBJ_INFO.shadow="dropdown" OBJ_INFO.options="OBJ_INFO_LINE"   
    export function GetVisionObjLineValue(parameter: any) {
        let index = parameter.SENTRY_INDEX.code;
        let num = parameter.NUM.code;
        let obj = parameter.OBJ_INFO.code;
        Generator.addCode([`sentry3_${index}.GetValue(Sentry3::kVisionLine,${obj},(int)${num})`, Generator.ORDER_UNARY_POSTFIX]);
    }

    //% block="  Sentry3[SENTRY_INDEX]  algo [VISION_TYPE]   [OBJ_INFO] of result [NUM]" blockType="reporter"
    //% SENTRY_INDEX.shadow="dropdown" SENTRY_INDEX.options="SENTRY_INDEX" SENTRY_INDEX.defl="1"
    //% VISION_TYPE.shadow="dropdown" VISION_TYPE.options="VISION_TYPE_STRING"
    //% NUM.shadow="number" NUM.defl=1
    //% OBJ_INFO.shadow="dropdown" OBJ_INFO.options="OBJ_INFO_QR"   
    export function GetVisionObjStringValue(parameter: any) {
        let index = parameter.SENTRY_INDEX.code;
        let vision_type = parameter.VISION_TYPE.code;
        let num = parameter.NUM.code;
        let obj = parameter.OBJ_INFO.code;
        Generator.addCode([`sentry3_${index}.GetValue(${vision_type},${obj},(int)${num})`, Generator.ORDER_UNARY_POSTFIX]);
    }

    //% block="  Sentry3[SENTRY_INDEX]  algo [VISION_TYPE]  string of decoding result [NUM]" blockType="reporter"
    //% SENTRY_INDEX.shadow="dropdown" SENTRY_INDEX.options="SENTRY_INDEX" SENTRY_INDEX.defl="1"
    //% VISION_TYPE.shadow="dropdown" VISION_TYPE.options="VISION_TYPE_STRING"
    //% NUM.shadow="number" NUM.defl=1
    export function GetString(parameter: any) {
        let index = parameter.SENTRY_INDEX.code;
        let vision_type = parameter.VISION_TYPE.code;
        let num = parameter.NUM.code;
        Generator.addCode([`String(sentry3_${index}.GetString(${vision_type}, (int)${num}))`, Generator.ORDER_UNARY_POSTFIX]);
    }

    //% block=" Sentry3[SENTRY_INDEX]  algo Color  recognized [COLOR_LABLE] result [NUM]" blockType="boolean"
    //% SENTRY_INDEX.shadow="dropdown" SENTRY_INDEX.options="SENTRY_INDEX" SENTRY_INDEX.defl="1"
    //% NUM.shadow="number" NUM.defl=1
    //% COLOR_LABLE.shadow="dropdown" COLOR_LABLE.options="COLOR_LABLE"   
    export function VisionDetectedColor(parameter: any) {
        let index = parameter.SENTRY_INDEX.code;
        let num = parameter.NUM.code;
        let obj = parameter.COLOR_LABLE.code;
        Generator.addCode([`sentry3_${index}.GetValue(Sentry3::kVisionColor,kLabel,(int)${num})==${obj}`, Generator.ORDER_UNARY_POSTFIX]);
    }

    //% block=" Sentry3[SENTRY_INDEX]  algo Blob  detected [COLOR_LABLE] blob result [NUM]" blockType="boolean"
    //% SENTRY_INDEX.shadow="dropdown" SENTRY_INDEX.options="SENTRY_INDEX" SENTRY_INDEX.defl="1"
    //% NUM.shadow="number" NUM.defl=1
    //% COLOR_LABLE.shadow="dropdown" COLOR_LABLE.options="COLOR_LABLE"   
    export function VisionDetectedBlob(parameter: any) {
        let index = parameter.SENTRY_INDEX.code;
        let num = parameter.NUM.code;
        let obj = parameter.COLOR_LABLE.code;
        Generator.addCode([`sentry3_${index}.GetValue(Sentry3::kVisionBlob,kLabel,(int)${num})==${obj}`, Generator.ORDER_UNARY_POSTFIX]);
    }


    //% block=" Sentry3[SENTRY_INDEX]  algo Yolo  recognized [YOLO_LABLE] result [NUM]" blockType="boolean"
    //% SENTRY_INDEX.shadow="dropdown" SENTRY_INDEX.options="SENTRY_INDEX" SENTRY_INDEX.defl="1"
    //% NUM.shadow="number" NUM.defl=1
    //% YOLO_LABLE.shadow="dropdown" YOLO_LABLE.options="YOLO_LABLE"   
    export function VisionDetectedYolo(parameter: any) {
        let index = parameter.SENTRY_INDEX.code;
        let num = parameter.NUM.code;
        let obj = parameter.YOLO_LABLE.code;
        Generator.addCode([`sentry3_${index}.GetValue(Sentry3::kVisionYolo,kLabel,(int)${num})==${obj}`, Generator.ORDER_UNARY_POSTFIX]);
    }

    //% block=" Sentry3[SENTRY_INDEX]  algo HandGesture  recognized thumb[THUMB] index[INDEX] middle[MIDDLE] ring[RING] pinky[PINKY] result [NUM]" blockType="boolean"
    //% SENTRY_INDEX.shadow="dropdown" SENTRY_INDEX.options="SENTRY_INDEX" SENTRY_INDEX.defl="1"
    //% NUM.shadow="number" NUM.defl=1
    //% THUMB.shadow="dropdown" THUMB.options="HANDPOSE_FINGER_STATE" THUMB.defl="ignore"
    //% INDEX.shadow="dropdown" INDEX.options="HANDPOSE_FINGER_STATE" INDEX.defl="ignore"
    //% MIDDLE.shadow="dropdown" MIDDLE.options="HANDPOSE_FINGER_STATE" MIDDLE.defl="ignore"
    //% RING.shadow="dropdown" RING.options="HANDPOSE_FINGER_STATE" RING.defl="ignore"
    //% PINKY.shadow="dropdown" PINKY.options="HANDPOSE_FINGER_STATE" PINKY.defl="ignore"
    export function VisionDetectedHandPoseCustom(parameter: any) {
        let index = parameter.SENTRY_INDEX.code;
        let num = parameter.NUM.code;
        let thumb_state = parameter.THUMB.code;
        let index_state = parameter.INDEX.code;
        let middle_state = parameter.MIDDLE.code;
        let ring_state = parameter.RING.code;
        let pinky_state = parameter.PINKY.code;

        // 计算mask和status
        // 位顺序：bit0(大拇指) bit1(食指) bit2(中指) bit3(无名指) bit4(小拇指)
        let mask = 0;
        let status = 0;

        // 大拇指 (bit 0)
        if (thumb_state !== 'ignore') {
            mask |= 0x01;
            if (thumb_state === 'extended') {
                status |= 0x01;
            }
        }

        // 食指 (bit 1)
        if (index_state !== 'ignore') {
            mask |= 0x02;
            if (index_state === 'extended') {
                status |= 0x02;
            }
        }

        // 中指 (bit 2)
        if (middle_state !== 'ignore') {
            mask |= 0x04;
            if (middle_state === 'extended') {
                status |= 0x04;
            }
        }

        // 无名指 (bit 3)
        if (ring_state !== 'ignore') {
            mask |= 0x08;
            if (ring_state === 'extended') {
                status |= 0x08;
            }
        }

        // 小拇指 (bit 4)
        if (pinky_state !== 'ignore') {
            mask |= 0x10;
            if (pinky_state === 'extended') {
                status |= 0x10;
            }
        }

        // 生成代码：((label & mask) == status)
        let mask_str = '0b' + ('00000' + mask.toString(2)).slice(-5);
        let status_str = '0b' + ('00000' + status.toString(2)).slice(-5);
        Generator.addCode([`((sentry3_${index}.GetValue(Sentry3::kVisionHandPose,kLabel,(int)${num}) & ${mask_str}) == ${status_str})`, Generator.ORDER_UNARY_POSTFIX]);
    }

    //% block=" Sentry3[SENTRY_INDEX]  algo HandGesture  recognized [HANDPOSE_PRESET] result [NUM]" blockType="boolean"
    //% SENTRY_INDEX.shadow="dropdown" SENTRY_INDEX.options="SENTRY_INDEX" SENTRY_INDEX.defl="1"
    //% NUM.shadow="number" NUM.defl=1
    //% HANDPOSE_PRESET.shadow="dropdown" HANDPOSE_PRESET.options="HANDPOSE_PRESET"
    export function VisionDetectedHandPosePreset(parameter: any) {
        let index = parameter.SENTRY_INDEX.code;
        let num = parameter.NUM.code;
        let preset = parameter.HANDPOSE_PRESET.code;

        // 去除前缀大写字母（如 A0b00010 -> 0b00010）
        let preset_value = preset.replace(/^[A-Z]/, '');

        // 生成代码：((label & 0b11111) == preset_value)
        Generator.addCode([`((sentry3_${index}.GetValue(Sentry3::kVisionHandPose,kLabel,(int)${num}) & 0b11111) == ${preset_value})`, Generator.ORDER_UNARY_POSTFIX]);
    }
}
